using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
using Newtonsoft.Json;
using System.Net;
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Kingdee
{
    [Icon("pack://application:,,,/Kingdee;component/Resources/Icon.png")]
    [OrderWeight(1)]
    [Category("金蝶云星空")]

    public class KingdeeServerCommand : Command, ICommandExecutableInServerSideAsync


    {

        [ComboProperty(
            ValueList = "查看表单|保存表单|提交|审核|反审核|删除|查询|下推|作废|业务关闭|反关闭|暂存|分配|分组保存|登出|工作流审批",
            DisplayList = "查看表单|保存表单|提交|审核|反审核|删除|查询|下推|作废|业务关闭|反关闭|暂存|分配|分组保存|登出|工作流审批")]
        [DisplayName("业务名称")]
        [Required]
        public string ActionName { get; set; } = "查看表单";

        [ComboProperty(
            ValueList = "SAL_SaleOrder|PUR_Requisition|SAL_OUTSTOCK|SAL_RETURNSTOCK|PUR_PurchaseOrder|STK_InStock|PUR_MRB|AR_receivable|AP_Payable|BD_MATERIAL|BD_Customer|SAL_MATERIALGROUP|BD_Supplier",
            DisplayList = "销售订单|采购申请单|销售出库单|销售退货单|采购订单|采购入库单|采购退料单|应收单|应付单|物料档案|客户|物料分组|供应商")]
        [DisplayName("单据名称")]
        [Required]
        public string ViewFormId { get; set; } = "SAL_SaleOrder";

        [FormulaProperty]
        [DisplayName("账套ID")]
        [Required]
        public object AcctID { get; set; } = "";

        [FormulaProperty]
        [DisplayName("用户名")]
        [Required]
        public object Username { get; set; } = "";

        [FormulaProperty]
        [PasswordPropertyText(true)]
        [DisplayName("密码")]
        [Required]
        public object Password { get; set; } = "";

        [FormulaProperty]
        [DisplayName("服务器地址")]
        [Required]
        public object BaseUrl { get; set; } = "";

        [FormulaProperty]
        [DisplayName("主键ID")]
        public object Id { get; set; } = "";

        [FormulaProperty]
        [DisplayName("单据编号")]
        public object Number { get; set; } = "";

        [ResultToProperty]
        [DisplayName("返回结果")]
        public string ResultTo { get; set; } = "结果";

        private static readonly HttpClient _http = new(new HttpClientHandler
        {
            UseCookies = true,
            CookieContainer = new CookieContainer()
        })
        { Timeout = TimeSpan.FromSeconds(30) };

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext ctx)
        {
            try
            {
                await LoginAsync(ctx);
                var result = await DoBusinessAsync(ctx);
                ctx.Parameters[ResultTo] = result;
                return new ExecuteResult();
            }
            catch (Exception ex)
            {
                ctx.Parameters[ResultTo] = JsonConvert.SerializeObject(new
                {
                    Success = false,
                    Message = ex.Message
                });
                return new ExecuteResult();
            }
        }

        private async Task LoginAsync(IServerCommandExecuteContext ctx)
        {
            var url = $"{(await ctx.EvaluateFormulaAsync(BaseUrl)).ToString().TrimEnd('/')}/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc";
            var loginObj = new
            {
                acctID = await ctx.EvaluateFormulaAsync(AcctID),
                username = await ctx.EvaluateFormulaAsync(Username),
                password = await ctx.EvaluateFormulaAsync(Password),
                lcid = 2052
            };
            string body = JsonConvert.SerializeObject(loginObj);
            using var resp = await _http.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json"));
            resp.EnsureSuccessStatusCode();
        }
        public override string ToString() => "金蝶云星空webapi插件";
        private async Task<string> DoBusinessAsync(IServerCommandExecuteContext ctx)
        {
            var url = $"{(await ctx.EvaluateFormulaAsync(BaseUrl)).ToString().TrimEnd('/')}/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.View.common.kdsvc";

            var idStr = (await ctx.EvaluateFormulaAsync(Id))?.ToString();
            _ = int.TryParse(idStr, out var idVal);

            var payload = new
            {
                formid = ViewFormId,
                data = new
                {
                    CreateOrgId = 0,
                    Id = idVal,
                    Number = (await ctx.EvaluateFormulaAsync(Number))?.ToString() ?? ""
                }
            };

            string body = JsonConvert.SerializeObject(payload);
            using var resp = await _http.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json"));
            return await resp.Content.ReadAsStringAsync();
        }
    }
}